using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using log4net;

namespace Triton.Common
{
	public class TypeFinder : ObservableCollection<object>
	{
		[CompilerGenerated]
		private sealed class Class234
		{
			public Type type_0;

			internal bool method_0(object object_0)
			{
				return object_0.GetType() == type_0;
			}
		}

		private static readonly ILog ilog_0 = LogManager.GetLogger(typeof(TypeFinder));

		[CompilerGenerated]
		private bool bool_0;

		[CompilerGenerated]
		private bool bool_1;

		[CompilerGenerated]
		private Type type_0;

		[CompilerGenerated]
		private ObservableCollection<Type> observableCollection_0;

		public bool IncludeGacAssemblies
		{
			[CompilerGenerated]
			get
			{
				return bool_0;
			}
			[CompilerGenerated]
			set
			{
				bool_0 = value;
			}
		}

		public bool CreateInstances
		{
			[CompilerGenerated]
			get
			{
				return bool_1;
			}
			[CompilerGenerated]
			set
			{
				bool_1 = value;
			}
		}

		public Type Type
		{
			[CompilerGenerated]
			get
			{
				return type_0;
			}
			[CompilerGenerated]
			private set
			{
				type_0 = value;
			}
		}

		public ObservableCollection<Type> InstanceTypes
		{
			[CompilerGenerated]
			get
			{
				return observableCollection_0;
			}
			[CompilerGenerated]
			set
			{
				observableCollection_0 = value;
			}
		}

		public TypeFinder(Type type, bool includeGacAssemblies = false, bool createInstances = true)
		{
			Type = type;
			IncludeGacAssemblies = includeGacAssemblies;
			CreateInstances = createInstances;
			InstanceTypes = new ObservableCollection<Type>();
			Refresh();
			AppDomain.CurrentDomain.AssemblyLoad += delegate(object sender, AssemblyLoadEventArgs e)
			{
				method_0(e.LoadedAssembly);
			};
		}

		private void method_0(Assembly assembly_0)
		{
			if (!IncludeGacAssemblies && assembly_0.GlobalAssemblyCache)
			{
				return;
			}
			Type[] types = assembly_0.GetTypes();
			foreach (Type type_2 in types)
			{
				if (!type_2.IsClass || this.Any((object object_0) => object_0.GetType() == type_2) || type_2.GetCustomAttributes(typeof(TypeFinderIgnoredAttribute)).Any())
				{
					continue;
				}
				if (Type.IsInterface)
				{
					if (!type_2.GetInterfaces().Any((Type type_1) => type_1 == Type))
					{
						continue;
					}
					ilog_0.Debug("Type " + type_2.Name + " implements interface " + Type.Name);
					try
					{
						InstanceTypes.Add(type_2);
						if (CreateInstances)
						{
							Add(Activator.CreateInstance(type_2));
						}
					}
					catch (MissingMethodException message)
					{
						ilog_0.Error(string.Concat("Could not instantiate class ", type_2, ". It does not have a public, parameterless constructor."));
						ilog_0.Error(message);
					}
					catch (Exception message2)
					{
						ilog_0.Error("Exception instantiating type " + type_2);
						ilog_0.Error(message2);
					}
				}
				else
				{
					if (!type_2.IsSubclassOf(Type))
					{
						continue;
					}
					ilog_0.Debug("Type " + type_2.Name + " inherits class " + Type.Name);
					try
					{
						InstanceTypes.Add(type_2);
						if (CreateInstances)
						{
							Add(Activator.CreateInstance(type_2));
						}
					}
					catch (MissingMethodException message3)
					{
						ilog_0.Error(string.Concat("Could not instantiate class ", type_2, ". It does not have a public, parameterless constructor."));
						ilog_0.Error(message3);
					}
					catch (Exception message4)
					{
						ilog_0.Error("Exception instantiating type " + type_2);
						ilog_0.Error(message4);
					}
				}
			}
		}

		public void Refresh()
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly_ in assemblies)
			{
				try
				{
					method_0(assembly_);
				}
				catch (ReflectionTypeLoadException)
				{
				}
				catch (TypeLoadException)
				{
				}
			}
		}

		[CompilerGenerated]
		private void method_1(object sender, AssemblyLoadEventArgs e)
		{
			method_0(e.LoadedAssembly);
		}

		[CompilerGenerated]
		private bool method_2(Type type_1)
		{
			return type_1 == Type;
		}
	}
	public class TypeFinder<T> : ObservableCollection<T>
	{
		[CompilerGenerated]
		private sealed class Class235
		{
			public Type type_0;

			internal bool method_0(T gparam_0)
			{
				return gparam_0.GetType() == type_0;
			}
		}

		private static readonly ILog ilog_0 = LogManager.GetLogger(typeof(TypeFinder<T>));

		[CompilerGenerated]
		private bool bool_0;

		[CompilerGenerated]
		private bool bool_1;

		[CompilerGenerated]
		private Type type_0;

		[CompilerGenerated]
		private ObservableCollection<Type> observableCollection_0;

		public bool IncludeGacAssemblies
		{
			[CompilerGenerated]
			get
			{
				return bool_0;
			}
			[CompilerGenerated]
			set
			{
				bool_0 = value;
			}
		}

		public bool CreateInstances
		{
			[CompilerGenerated]
			get
			{
				return bool_1;
			}
			[CompilerGenerated]
			set
			{
				bool_1 = value;
			}
		}

		public Type Type
		{
			[CompilerGenerated]
			get
			{
				return type_0;
			}
			[CompilerGenerated]
			private set
			{
				type_0 = value;
			}
		}

		public ObservableCollection<Type> InstanceTypes
		{
			[CompilerGenerated]
			get
			{
				return observableCollection_0;
			}
			[CompilerGenerated]
			set
			{
				observableCollection_0 = value;
			}
		}

		public TypeFinder(bool includeGacAssemblies, bool createInstances = true)
		{
			Type = typeof(T);
			IncludeGacAssemblies = includeGacAssemblies;
			CreateInstances = createInstances;
			InstanceTypes = new ObservableCollection<Type>();
			Refresh();
			AppDomain.CurrentDomain.AssemblyLoad += delegate(object sender, AssemblyLoadEventArgs e)
			{
				method_0(e.LoadedAssembly);
			};
		}

		private void method_0(Assembly assembly_0)
		{
			if (!IncludeGacAssemblies && assembly_0.GlobalAssemblyCache)
			{
				return;
			}
			Type[] types = assembly_0.GetTypes();
			foreach (Type type_2 in types)
			{
				if (!type_2.IsClass || this.Any((T gparam_0) => gparam_0.GetType() == type_2) || type_2.GetCustomAttributes(typeof(TypeFinderIgnoredAttribute)).Any())
				{
					continue;
				}
				if (Type.IsInterface)
				{
					if (!type_2.GetInterfaces().Any((Type type_1) => type_1 == Type))
					{
						continue;
					}
					ilog_0.Debug("Type " + type_2.Name + " implements interface " + Type.Name);
					try
					{
						InstanceTypes.Add(type_2);
						if (CreateInstances)
						{
							Add((T)Activator.CreateInstance(type_2));
						}
					}
					catch (MissingMethodException message)
					{
						ilog_0.Error(string.Concat("Could not instantiate class ", type_2, ". It does not have a public, parameterless constructor."));
						ilog_0.Error(message);
					}
					catch (Exception message2)
					{
						ilog_0.Error("Exception instantiating type " + type_2);
						ilog_0.Error(message2);
					}
				}
				else
				{
					if (!type_2.IsSubclassOf(Type))
					{
						continue;
					}
					ilog_0.Debug("Type " + type_2.Name + " inherits class " + Type.Name);
					try
					{
						InstanceTypes.Add(type_2);
						if (CreateInstances)
						{
							Add((T)Activator.CreateInstance(type_2));
						}
					}
					catch (MissingMethodException message3)
					{
						ilog_0.Error(string.Concat("Could not instantiate class ", type_2, ". It does not have a public, parameterless constructor."));
						ilog_0.Error(message3);
					}
					catch (Exception message4)
					{
						ilog_0.Error("Exception instantiating type " + type_2);
						ilog_0.Error(message4);
					}
				}
			}
		}

		public void Refresh()
		{
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			foreach (Assembly assembly_ in assemblies)
			{
				try
				{
					method_0(assembly_);
				}
				catch (ReflectionTypeLoadException)
				{
				}
				catch (TypeLoadException)
				{
				}
			}
		}

		[CompilerGenerated]
		private void method_1(object sender, AssemblyLoadEventArgs e)
		{
			method_0(e.LoadedAssembly);
		}

		[CompilerGenerated]
		private bool method_2(Type type_1)
		{
			return type_1 == Type;
		}
	}
}
